package bookworm;

import java.util.Collections;
import java.util.LinkedList;

import comparators.ComparatorOfBooksAndAverareRating;

import visitorpattern.CreatesVisitorsAndVisitsGraph;

/**
 * This class will look for authors that wrote books from the tag passed as parameter.
 * For each author of our system, this class will use the createsAndVisitsGraph to
 * search for all books written by this author(and for all books from specified tag written
 * by the author too). After this, it'll get the average rating of each author for the specified tag
 * (did the author wrote good books about the tag?) and sort the LinkedList 
 * "bestAuthorsBooksAndRatingsBasedOnTag" based on this average rating.
 * @author Mina
 *
 */
public class SearchBestAuthorsBasedOnTag 
{
	private String tag;
	private LinkedList<BooksAndRatingOfOneAuthor> bestAuthorsBooksAndRatingsBasedOnTag;
	private CreatesVisitorsAndVisitsGraph createsAndVisitsGraph;
	
	public SearchBestAuthorsBasedOnTag(String tag)
	{
		this.tag = tag;
		this.bestAuthorsBooksAndRatingsBasedOnTag =
				new LinkedList<BooksAndRatingOfOneAuthor>();
		this.createsAndVisitsGraph = new CreatesVisitorsAndVisitsGraph();
		this.searchForBestAuthorsOfTag();
		this.organizeBestAuthorsOfTag();
	}
	
	public LinkedList<BooksAndRatingOfOneAuthor> 
									getBestAuthorsBooksAndRatingsBasedOnTag()
	{
		return this.bestAuthorsBooksAndRatingsBasedOnTag;
	}
	
	
	
	/**
	 * function below will search on all book reviews from all authors of our system
	 * and calculate for each author if it is good(average rating > 2) based on tag
	 */
	private void searchForBestAuthorsOfTag()
	{
		LinkedList<String> allAuthorsUsedByTheSystem = 
				AdministratorOfAllAuthorsUsedByTheSystem.getAllAuthorsUsedByTheSystem();
		for(int i = 0; i < allAuthorsUsedByTheSystem.size(); i++)
		{
			String oneAuthor = allAuthorsUsedByTheSystem.get(i);
			BooksAndRatingOfOneAuthor booksAndRatingOfOneAuthor =
											this.getBooksAndRatingOfOneAuthor(oneAuthor);
			int ratingOfAuthorBasedOnTag = 
					booksAndRatingOfOneAuthor.getAverageRatingOfAuthorBasedOnTag();
			if(ratingOfAuthorBasedOnTag > 2)
			{
				//we found one of the best authors
				this.bestAuthorsBooksAndRatingsBasedOnTag.add(booksAndRatingOfOneAuthor);
			}
		}
	}
	
	private BooksAndRatingOfOneAuthor getBooksAndRatingOfOneAuthor(String author)
	{
		BooksAndRatingOfOneAuthor booksAndRatingOfAuthor = 
				this.createsAndVisitsGraph.getBooksAndAverageRatingOfSpecificAuthorBasedOnTag(author, tag);
		return booksAndRatingOfAuthor;
	}
	
	/**
	 * organizes the linkedList "bestAuthorsBooksAndRatingsBasedOnTag" by descending order
	 */
	private void organizeBestAuthorsOfTag()
	{
		ComparatorOfBooksAndAverareRating comparator = new ComparatorOfBooksAndAverareRating();
		Collections.sort(this.bestAuthorsBooksAndRatingsBasedOnTag, comparator);
	}
}
